package sns.dao;

import java.util.List;
import org.hibernate.Query;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import sns.bean.Relation;
import sns.bean.User;

public class RelationDao extends HibernateDaoSupport {

	public void save(Relation relation){
		getSession().save(relation);
	}
	
	public void merge(Relation relation){
		getSession().merge(relation);
	}
	
	public void delete(Relation relation){
		getSession().delete(relation);
	}
	
	/**
	 * Get the relation object of which source and target are the same as parameters. 
	 * 
	 * @param source
	 * @param target
	 * @return
	 */
	public Relation getRelation(User source, User target){
		if(source==null||target==null){
			return null;
		}
		Query q = getSession().createQuery("select relation from Relation as relation where relation.source.iduser = :sourceid and relation.target.iduser = :targetid");
		q.setLong("sourceid", source.getIduser());
		q.setLong("targetid", target.getIduser());
		return (Relation)q.uniqueResult();
	}
	
	/**
	 * Check if user1 has followed user2.
	 * 
	 * @param user1
	 * @param user2
	 * @return
	 */
	public boolean checkIfFollow(User user1, User user2){
		if(getRelation(user1, user2)==null){
			return false;
		}else{
			return true;
		}
	}
	
	/**
	 * Get the number of followers(i.e. the number of fans)
	 * 
	 * @param user
	 * @return
	 */
	public int getFollowerNum(User user){
		if(user==null){
			return 0;
		}
		Query q = getSession().createQuery("select count(*) from Relation as relation where relation.target.iduser=:targetid");
		q.setLong("targetid", user.getIduser());
		return ((Long)q.uniqueResult()).intValue();
	}
	
	/**
	 * Get the number of followees(i.e. the number of idols)
	 * 
	 * @param user
	 * @return
	 */
	public int getFolloweeNum(User user){
		if(user==null){
			return 0;
		}
		Query q = getSession().createQuery("select count(*) from Relation as relation where relation.source.iduser=:sourceid");
		q.setLong("sourceid", user.getIduser());
		return ((Long)q.uniqueResult()).intValue();
	}
	
	/**
	 * Get the hottest users from min-th to max-th 
	 * 
	 * @param min
	 * @param max
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<User> getHotUsers(int min, int max){
		if(min<0||min>max){
			return null;
		}
		Query q = getSession().createQuery("select relation.target from Relation as relation group by relation.target order by count(relation.source) desc");
		q.setFirstResult(min);
		q.setMaxResults(max);
		return (List<User>)q.list();
	}
	
	/**
	 * get the followers, i.e. fans
	 * 
	 * @param user
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<User> getFollowers(User user){
		if(user==null){
			return null;
		}
		Query q = getSession().createQuery("select relation.source from Relation as relation where relation.target.id = :targetid order by relation.followtime desc");
		q.setLong("targetid", user.getIduser());
		return (List<User>)q.list();
	}
	
	/**
	 * Fetch the followers of the user from min-th to max-th
	 * 
	 * @param user
	 * @param min
	 * @param max
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<User> getMinMaxFollowers(User user, int min, int max){
		if(user==null||min<0||min>max){
			return null;
		}
		Query q = getSession().createQuery("select relation.source from Relation as relation where relation.target.id = :targetid order by relation.followtime desc");
		q.setLong("targetid", user.getIduser());
		q.setFirstResult(min);
		q.setMaxResults(max);
		return (List<User>)q.list();
	}
	
	/**
	 * get the followees, i.e. idols
	 * 
	 * @param user
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<User> getFollowees(User user){
		if(user==null){
			return null;
		}
		Query q = getSession().createQuery("select relation.target from Relation as relation where relation.source.id = :sourceid order by relation.followtime desc");
		q.setLong("sourceid", user.getIduser());
		return (List<User>)q.list();
	}
	
	/**
	 * Fetch the followees of the user from min-th to max-th
	 * 
	 * @param user
	 * @param min
	 * @param max
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<User> getMinMaxFollowees(User user, int min, int max){
		if(user==null||min<0||min>max){
			return null;
		}
		Query q = getSession().createQuery("select relation.target from Relation as relation where relation.source.id = :sourceid order by relation.followtime desc");
		q.setLong("sourceid", user.getIduser());
		q.setFirstResult(min);
		q.setMaxResults(max);
		return (List<User>)q.list();
	}
}
